package com.apes.fn.crm.customerExpand;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.business.carAccident.repository.CarAccidentRepository;
import com.apes.fn.business.fixedLoss.repository.LossQuotationRepository;
import com.apes.fn.server.pickUpCar.model.PickUpCar;
import com.apes.fn.server.pickUpCar.repository.PickUpCarRepository;
import com.apes.fn.server.servicePlan.repository.ServicePlanRepository;
import com.apes.fn.server.servicePlan.service.ServicePlanceService;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.car.model.CarConfiguration;
import com.apes.scm.masterdata.car.repository.CarConfigurationRepository;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.party.service.PartyService;
import org.apache.xmlbeans.impl.xb.xsdschema.Public;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/***
 * 会员车辆扩展信息service
 */
@Service("fnCustomerExpandService")
public class FnCustomerExpandService extends DomainService {

    @Autowired
    FnCustomerExpandRepository customerExpandRepository;
    @Autowired
    PartyService partyService;
    @Autowired
    PartyRoleRepository partyRoleRepository;
    @Autowired
    DeptRepository deptRepository;
    @Autowired
    ServicePlanRepository servicePlanRepository;
    @Autowired
    PickUpCarRepository pickUpCarRepository;
    @Autowired
    CarAccidentRepository carAccidentRepository;
    @Autowired
    LossQuotationRepository lossQuotationRepository;
    @Autowired
    CarConfigurationRepository carConfigurationRepository;
    @Autowired
    FnCustomerExpandDao fnCustomerExpandDao;
    @Autowired
    FnCustomerInfoService fnCustomerInfoService;
    /***
     * 默认传入字段 customer customerCar
     * @param request
     * @return
     */
    public FnCustomerExpand updateOrInsert(SimpleRequest request){
        JSONObject tempJson = request.getJO();
        FnCustomerExpand customerExpand;

        if (tempJson.get("customerExpand") != null && tempJson.getJSONObject("customerExpand").get("id") != null) {
            customerExpand = customerExpandRepository.findOne(tempJson.getJSONObject("customerExpand").getString("id"));
        } else {
            customerExpand = new FnCustomerExpand();
        }
        setCustomer(customerExpand, tempJson.get("customer") != null ? tempJson.getJSONObject("customer") : null);
        setCustomerCar(customerExpand, tempJson.get("customerCar") != null ? tempJson.getJSONObject("customerCar") : null);
        return customerExpandRepository.saveAndFlush(customerExpand);
    }


    private void setCustomer(FnCustomerExpand customerExpand, JSONObject param) {
        // 如果参数不存在或者与手机号之前不一致，清空所有数据
        if(param == null || (customerExpand.getMobile() != null &&  !customerExpand.getMobile().equals(param.getString("mobile")))){
            customerExpand.setUserId(null);
            customerExpand.setRealname(null);
            customerExpand.setMobile(null);

            customerExpand.setSex(null);
            customerExpand.setSexLabel(null);

            customerExpand.setUserRoleId(null);
            customerExpand.setUserRoleName(null);

            customerExpand.setCustomerLevelId(null);
            customerExpand.setCustomerLevelName(null);

            customerExpand.setCustomerLivenessId(null);
            customerExpand.setCustomerLivenessName(null);
        }

        if( param == null ) return;

        if( param.get("userId") != null ) customerExpand.setUserId( param.getLong("userId"));

        if( param.get("realname") != null ) customerExpand.setRealname( param.getString("realname"));
        if( param.get("mobile") != null ) customerExpand.setMobile( param.getString("mobile"));

        if( param.get("sex") != null ) customerExpand.setSex( param.getInteger("sex"));
        if( param.get("sexLabel") != null ) customerExpand.setSexLabel( param.getString("sexLabel"));

        if( param.get("userRole") != null ) customerExpand.setUserRoleId( param.getJSONObject("userRole").getString("id"));
        if( param.get("userRole") != null ) customerExpand.setUserRoleName( param.getJSONObject("userRole").getString("name"));

        if( param.get("userRole") != null ) customerExpand.setUserRoleId( param.getJSONObject("userRole").getString("id"));
        if( param.get("userRole") != null ) customerExpand.setUserRoleName( param.getJSONObject("userRole").getString("name"));

        if( param.get("level") != null ) customerExpand.setCustomerLevelId( param.getString("level"));
        if( param.get("levelLabel") != null ) customerExpand.setCustomerLevelName( param.getString("levelLabel"));
        if( param.get("activit") != null ) customerExpand.setCustomerLivenessId( param.getString("activit"));
        if( param.get("activityLabel") != null ) customerExpand.setCustomerLivenessName( param.getString("activityLabel"));
    }

    private void setCustomerCar(FnCustomerExpand customerExpand, JSONObject param) {
        // 如果参数不存在或者与之前不一致，清空所有数据
        if( param == null ||  (customerExpand.getCarLicense() != null &&  !customerExpand.getCarLicense().equals(param.getLong("id")))){
            customerExpand.setVin( null);
            customerExpand.setCarLicense( null);

            customerExpand.setJekunModelCode( null);
            customerExpand.setCarModelLabel( null);

            customerExpand.setUnitClientId(null);
            customerExpand.setUnitClientName(null);

            customerExpand.setVendorCode(null);
            customerExpand.setVendorName(null);
        }
        if( param == null ) return;

        if( param.get("vin") != null ) customerExpand.setVin( param.getString("vin"));
        if( param.get("carLicense") != null ) customerExpand.setCarLicense( param.getString("carLicense"));

        if( param.get("jekunModelCode") != null ) customerExpand.setJekunModelCode( param.getString("jekunModelCode"));
        if( param.get("carModelLabel") != null ) customerExpand.setCarModelLabel( param.getString("carModelLabel"));

        if( param.get("unitClient") != null ) customerExpand.setUnitClientId( param.getJSONObject("unitClient").getString("clientCode"));
        if( param.get("unitClient") != null ) customerExpand.setUnitClientName( param.getJSONObject("unitClient").getString("clientName"));

        if( param.get("vendorCode") != null ) customerExpand.setVendorCode( param.getString("vendorCode"));
        if( param.get("vendorName") != null ) customerExpand.setVendorName( param.getString("vendorName"));

    }


    /***
     * App数据同步接口，用于修改当前线下的缓存数据
     */
    public JSONObject synAppCustomerCar(SimpleRequest request) {

        JSONObject returnJson = new JSONObject();
        JSONArray updateItem = new JSONArray();
        JSONObject tempJson = request.getJO();

        // 处理数据
        String accessProvider = tempJson.getString("accessProvider"); // 接入商编码
        String carLicense = tempJson.getString("carLicense"); // 车牌号
        String vin = tempJson.getString("vin");  //车架号
        String jekunModelCode = tempJson.getString("jekunModelCode"); // 配置车型编码
        String carModelLabel = tempJson.getString("carModelLabel"); //  配置车型名称

        // 获取当前接入商下的所有公司
        List<PartyRole> companyList = partyRoleRepository.findByAccessProvider(accessProvider);

        if (companyList.size() == 0) throw new RuntimeException("通过当前接入商未找到对应的公司，接入商编码:" + accessProvider);

        // 筛选并去重数据
        // 通过公司找门店并组合为数组
        // 通过门店找扩展表
        Map<String, List<FnCustomerExpand>> groupByCustomerExpand = companyList.stream()
                .map(company -> deptRepository.findAll(JpaDsl.toCriteriaByEq(
                        "company.id", company.getId()
                )))
                .filter(depts -> depts.size() != 0)
                .reduce(new ArrayList<Dept>(), (a, b) -> { b.addAll(a); return b; }).stream()
                .map(dept -> SpringManager.getBean(ServicePlanceService.class).findValidServiceFnCustomerExpand(dept, carLicense))
                .filter( customerExpand ->  customerExpand != null)
                .collect(Collectors.groupingBy(FnCustomerExpand::getId));


        groupByCustomerExpand.forEach((id, customerExpandList) -> {
            FnCustomerExpand customerExpand = customerExpandList.get(0);
            // 保存最新的数据
            customerExpand.setVin(vin);
            customerExpand.setJekunModelCode(jekunModelCode);
            customerExpand.setCarModelLabel(carModelLabel);
            customerExpandRepository.saveAndFlush(customerExpand);

            // 获取对应的服务方案 接车单 定损报案单 定损报价单进行保存修改对应的version
            // 防止门店直接在界面进行处理还是使用原本的数据

            servicePlanRepository.findAll(JpaDsl.toCriteriaByEq(
                    "fnCustomerExpand.id", customerExpand.getId()
            )).stream().forEach(servicePlan -> {
                servicePlan.setLastUpdatedStamp(new Date());
                servicePlanRepository.save(servicePlan);
            });

            pickUpCarRepository.findAll(JpaDsl.toCriteriaByEq(
                    "fnCustomerExpand.id", customerExpand.getId()
            )).forEach(pickUpCar -> {
                pickUpCar.setLastUpdatedStamp(new Date());
                pickUpCarRepository.save(pickUpCar);
            });

            carAccidentRepository.findAll(JpaDsl.toCriteriaByEq(
                    "customerExpand.id", customerExpand.getId()
            )).forEach(carAccident -> {
                carAccident.setLastUpdatedStamp(new Date());
                carAccidentRepository.save(carAccident);
            });

            lossQuotationRepository.findAll(JpaDsl.toCriteriaByEq(
                    "customerExpand.id", customerExpand.getId()
            )).forEach(lossQuotation -> {
                lossQuotation.setLastUpdatedStamp(new Date());
                lossQuotationRepository.save(lossQuotation);
            });

            updateItem.add(MapUtil.mapper(
                    "accessProvider",accessProvider,
                    "carLicense", customerExpand.getCarLicense(),
                    "customerExpandId", customerExpand.getId()
            ));
        });



        returnJson.put("item", updateItem);
        returnJson.put("msg", "同步成功，更新条数：" + updateItem.size());

        return returnJson;
    }

    /**
     * 根据接车类型，生成
     * @param pickUpCar
     */
    public FnCustomerExpand saveFncustomerExpandPickUpType(PickUpCar pickUpCar) {
        FnCustomerExpand fnCustomerExpand = pickUpCar.getFnCustomerExpand();
        if(fnCustomerExpand == null) throw new RuntimeException("生成接车单，车辆扩展表数据有误");
        //记录扩展表的接车类型
        List<PickUpTypeF> pickUpTypeFS = pickUpCar.getPickUpTypes().stream().map(pickUpType -> {
            PickUpTypeF pickUpTypeF = new PickUpTypeF();
            pickUpTypeF.setFnCustomerExpand(fnCustomerExpand);
            pickUpTypeF.setId(SpringManager.getBean(SequenceService.class).getId(PickUpTypeF.CONST_TABLE_NAME));
            pickUpTypeF.setPickUpType(pickUpType.getPickUpType());
            pickUpTypeF.setRemarks(pickUpType.getRemarks());
            return pickUpTypeF;
        }).collect(Collectors.toList());
        fnCustomerExpand.setPickUpTypeF(pickUpTypeFS);
        return customerExpandRepository.saveAndFlush(fnCustomerExpand);
    }


    /**
     * 手动分页
     * @param jo
     * @param cross
     * @return
     */
    public PageImpl pageInfo(JSONObject jo, List cross, Boolean fixPage){
        int fixNum = 0;
        if (fixPage)fixNum+=1;
        int size = ((Integer) jo.get("page")-fixNum)*(Integer) jo.get("size");
        List result = new ArrayList<>();
        for (int i = size+1; i <= size+(Integer) jo.get("size"); i++) {
            if (cross.size()>=i)result.add(cross.get(i-1));
        }
        Pageable pageable = PageRequest.of(((Integer) jo.get("page")), (Integer) jo.get("size"));
        PageImpl page = new PageImpl(result, pageable, cross.size());
        return page;
    }

    /**
     * 查询车型配置
     * @param request
     * @return
     */
    public Object findCarConfiguration(SimpleRequest request){
        JSONObject jo = request.getJO();
        if (!jo.containsKey("jekunModelCode")){
            return MapUtil.mapper("carConfiguration",null,
                    "carLabel",null,
                    "carModel",null);
        }
        CarConfiguration carConfiguration = carConfigurationRepository.findOne(jo.getString("jekunModelCode"));
        if (carConfiguration == null) {
            return MapUtil.mapper("carConfiguration",null,
                    "carLabel",null,
                    "carModel",null);
        }
        return MapUtil.mapper("carConfiguration",carConfiguration,
                               "carLabel",carConfiguration.getCarLabel(),
                               "carModel",carConfiguration.getCarModel());
    }

    public String accordIdFindCarLicense(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        return customerExpandRepository.findOne(getJO.getString("id")).getCarLicense();
    }
    public JSONArray findNoCreateInfoData(SimpleRequest request){
        JSONArray noCreateInfoData = fnCustomerExpandDao.findNoCreateInfoData(request.getJO());
        if (noCreateInfoData.isEmpty())noCreateInfoData = fnCustomerExpandDao.findNoCreateInfoDataByEmptyVendorCode(request.getJO());

        return noCreateInfoData;
    }
    public void fnCustomerExpandCreateInfo(SimpleRequest request){
        JSONObject jo = request.getJO();
        FnCustomerExpand fnCustomerExpand = customerExpandRepository.findOne(jo.getString("ID"));
        fnCustomerInfoService.generateOrUpdateFnCustomerInfo(fnCustomerExpand);
    }

    public Object runFnCustomerInfoData(SimpleRequest request){
        JSONArray noCreateInfoData = fnCustomerExpandDao.findNoCreateInfoData(request.getJO());
        if (noCreateInfoData.isEmpty())noCreateInfoData = fnCustomerExpandDao.findNoCreateInfoDataByEmptyVendorCode(request.getJO());

        while (!noCreateInfoData.isEmpty()){
            noCreateInfoData.forEach(o -> {
                JSONObject jsonObject = (JSONObject) o;
                FnCustomerExpand fnCustomerExpand = customerExpandRepository.findOne(jsonObject.getString("ID"));
                fnCustomerInfoService.generateOrUpdateFnCustomerInfo(fnCustomerExpand);
            });
            noCreateInfoData = fnCustomerExpandDao.findNoCreateInfoData(request.getJO());
            if (noCreateInfoData.isEmpty())noCreateInfoData = fnCustomerExpandDao.findNoCreateInfoDataByEmptyVendorCode(request.getJO());
        }

        return "success";
    }
}
